/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = rtsp_core.h                                        */
/*  NOTE      =                                                    */
/*  DATE      = 2015/07/14 by songbb                               */
/*******************************************************************/

#ifndef __RTSP_CORE_H_
#define __RTSP_CORE_H_

#include "frlist.h"
#include "frhash2.h"
#include "frstr.h"
#include "frreport_comm.h"

#include "conntrack.h"
#include "module.h"
#include "frbyte_buffer.h"

typedef enum __em_req_method {
    RTSP_METHOD_TYPE_UNKNOWN = 0,
    RTSP_METHOD_TYPE_OPTIONS,
    RTSP_METHOD_TYPE_DESCRIBE,
    RTSP_METHOD_TYPE_ANNOUNCE,
    RTSP_METHOD_TYPE_SETUP,
    RTSP_METHOD_TYPE_PLAY,
    RTSP_METHOD_TYPE_PAUSE,
    RTSP_METHOD_TYPE_TEARDOWN,
    RTSP_METHOD_TYPE_GET_PARAMETER,
    RTSP_METHOD_TYPE_SET_PARAMETER,
    RTSP_METHOD_TYPE_REDIRECT,
    RTSP_METHOD_TYPE_RECORD
} Rtsp_req_method;

/**
 * RTSP协议头域
 */
typedef struct __st_rtsp_header
{
    unsigned int ui_content_length;
} Rtsp_header;

/*
 * L7session_rtsp 用于存放RTSP私有的session数据，对应L7_session的p_session_private变量
 */
typedef struct __st_L7session_rtsp
{
    unsigned long long ull_error_nums;
    unsigned long long ull_unfinshed_fragmented_packets;
    char *p_username;
    char *p_server;
} L7session_rtsp;

/**
 * 分片的状态
 */
typedef enum __em_fragment_state {
    APM_RTSP_FRAGMENT_INIT,
    APM_RTSP_FRAGMENT_NEED_NEXT_REQ_PACKET,
    APM_RTSP_FRAGMENT_NEED_NEXT_RESP_PACKET
} Rtsp_fragment_state;

/**
 * RTSP数据包结构体
 */
typedef struct __st_L7_rtsp_packet
{
    Rtsp_fragment_state fragment_state;  /* 当前的分片状态 */
    Frbyte_Packet *p_st_packet;         /* 组包完成的数据 */
    int i_is_rtsp_req;                   /* RTSP协议层的请求 */
    unsigned int ui_length;             /* 完整的一个RTSP请求或者响应的长度 */
    unsigned int ui_content_length;     /* RTSP message body的长度*/
    char *p_req_method;
    Rtsp_req_method em_req_method;
    struct timeval st_timestamp_first;  /* 第一个请求的分片包的时间 */
    struct timeval st_timestamp_last;   /* 最后一个请求的分片包的时间 */
} L7_rtsp_packet;

/**
 * RTSP一次交互过程，一次REGISTER或者一次INVITE过程，从request发起开始到收到一个非临时性应答为止
 */
typedef struct __st_L7_rtsp_stmt
{
    Rtsp_req_method em_req_method;
    struct timeval st_req_end_timestamp;
    struct timeval st_resp_start_timestamp;
    unsigned long ul_resp_server_time_us;
    unsigned long ul_resp_bytes;
} L7_rtsp_stmt;

/**
 * RTSP私有结构体
 */
typedef struct __st_L7session_rtsp_private
{
    L7session_rtsp *p_st_sess;            /* session数据 */
    L7_rtsp_stmt *p_st_rtsp_stmt;          /* RTSP一次交互过程 */
    L7_rtsp_packet *p_st_rtsp_packet;      /* 当前处理中的RTSP数据包 */
    Frlist_header *p_report_comm;        /* 用于临时存储report的公共部分数据 */
    Frlist_header *p_report_req;         /* 用于临时存储report的请求部分数据 */
    L7_session *p_st_session;            /* 指向父级的L7_session结构体 */
} L7session_rtsp_private;

void rtsp_core_add_unfinshed_fragmented_packets(L7session_rtsp *p_st_sess);

int rtsp_detect(Conntrack *p_st_conn
            , Apm_packet *p_st_packet);

int rtsp_analyze(Conntrack *p_st_conn
                , Apm_packet *p_st_packet
                , Frhash_header *p_st_hash_report);

int rtsp_session_destory(void *p_st_session_private_in);

#endif
